home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / liboctave / Array.h < prev    next >
C/C++ Source or Header  |  1997-05-26  |  5KB  |  261 lines

  1. // Template array classes
  2. /*
  3.  
  4. Copyright (C) 1996 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22. */
  23.  
  24. #if !defined (octave_Array_h)
  25. #define octave_Array_h 1
  26.  
  27. #if defined (__GNUG__)
  28. #pragma interface
  29. #endif
  30.  
  31. #include <cassert>
  32. #include <cstdlib>
  33.  
  34. class idx_vector;
  35.  
  36. // For now, define this here if it is not already defined.  Not doing
  37. // this can result in bugs that are very hard to find.
  38.  
  39. #ifndef HEAVYWEIGHT_INDEXING
  40. #define HEAVYWEIGHT_INDEXING 1
  41. #endif
  42.  
  43. // One dimensional array class.  Handles the reference counting for
  44. // all the derived classes.
  45.  
  46. template <class T>
  47. class Array
  48. {
  49. private:
  50.  
  51. // The real representation of all arrays.
  52.  
  53.   class ArrayRep
  54.   {
  55.   public:
  56.  
  57.     T *data;
  58.     int len;
  59.     int count;
  60.  
  61.     ArrayRep& operator = (const ArrayRep& a);
  62.  
  63.     ArrayRep (T *d, int l) : data (d), len (l), count (1) { }
  64.  
  65.     ArrayRep (void) : data (0), len (0), count (1) { }
  66.  
  67.     ArrayRep (int n) : data (new T [n]), len (n), count (1) { }
  68.  
  69.     ArrayRep (const ArrayRep& a)
  70.       : data (new T [a.len]), len (a.len), count (1)
  71.     {
  72.       for (int i = 0; i < len; i++)
  73.         data[i] = a.data[i];
  74.     }
  75.  
  76.     ~ArrayRep (void) { delete [] data; }
  77.  
  78.     int length (void) const { return len; }
  79.  
  80.     T& elem (int n) { return data[n]; }
  81.  
  82.     T elem (int n) const { return data[n]; }
  83.  
  84.     void qsort (int (*compare) (const void *, const void *))
  85.       {
  86.     ::qsort (data, len, sizeof (T), compare);
  87.       }
  88.   };
  89.  
  90.   void make_unique (void)
  91.     {
  92.       if (rep->count > 1)
  93.     {
  94.       --rep->count;
  95.       rep = new ArrayRep (*rep);
  96.     }
  97.     }
  98.  
  99. #ifdef HEAVYWEIGHT_INDEXING
  100.   idx_vector *idx;
  101.   int max_indices;
  102.   int idx_count;
  103. #endif
  104.  
  105. protected:
  106.  
  107.   ArrayRep *rep;
  108.  
  109.   Array (T *d, int l)
  110.     {
  111.       rep = new ArrayRep (d, l);
  112.  
  113. #ifdef HEAVYWEIGHT_INDEXING
  114.       idx = 0;
  115.       max_indices = 1;
  116.       idx_count = 0;
  117. #endif
  118.     }
  119.  
  120. public:
  121.  
  122.   Array (void)
  123.     {
  124.       rep = new ArrayRep ();
  125.  
  126. #ifdef HEAVYWEIGHT_INDEXING
  127.       idx = 0;
  128.       max_indices = 1;
  129.       idx_count = 0;
  130. #endif
  131.     }
  132.  
  133.   Array (int n)
  134.     {
  135.       rep = new ArrayRep (n);
  136.  
  137. #ifdef HEAVYWEIGHT_INDEXING
  138.       idx = 0;
  139.       max_indices = 1;
  140.       idx_count = 0;
  141. #endif
  142.     }
  143.  
  144.   Array (int n, const T& val);
  145.  
  146.   Array (const Array<T>& a)
  147.     {
  148.       rep = a.rep;
  149.       rep->count++;
  150.  
  151. #ifdef HEAVYWEIGHT_INDEXING
  152.       max_indices = a.max_indices;
  153.       idx_count = 0;
  154.       idx = 0;
  155. #endif
  156.     }
  157.  
  158.   ~Array (void);
  159.  
  160.   Array<T>& operator = (const Array<T>& a);
  161.  
  162.   int capacity (void) const { return rep->length (); }
  163.   int length (void) const { return rep->length (); }
  164.  
  165.   // No checking, even for multiple references, ever.
  166.  
  167.   T& xelem (int n) { return rep->elem (n); }
  168.   T xelem (int n) const { return rep->elem (n); }
  169.  
  170.   // XXX FIXME XXX -- would be nice to fix this so that we don't
  171.   // unnecessarily force a copy, but that is not so easy, and I see no
  172.   // clean way to do it.
  173.  
  174.   T& checkelem (int n)
  175.     {
  176.       if (n < 0 || n >= rep->length ())
  177.     return range_error ("T& Array<T>::checkelem", n);
  178.       else
  179.     {
  180.       make_unique ();
  181.       return xelem (n);
  182.     }
  183.     }
  184.  
  185.   T& elem (int n)
  186.     {
  187.       make_unique ();
  188.       return xelem (n);
  189.     }
  190.  
  191. #if defined (BOUNDS_CHECKING)
  192.   T& operator () (int n) { return checkelem (n); }
  193. #else
  194.   T& operator () (int n) { return elem (n); }
  195. #endif
  196.  
  197.   T checkelem (int n) const
  198.     {
  199.       if (n < 0 || n >= rep->length ())
  200.     return range_error ("T Array<T>::checkelem", n);
  201.       else
  202.     return xelem (n);
  203.     }
  204.  
  205.   T elem (int n) const { return xelem (n); }
  206.  
  207. #if defined (BOUNDS_CHECKING)
  208.   T operator () (int n) const { return checkelem (n); }
  209. #else
  210.   T operator () (int n) const { return elem (n); }
  211. #endif
  212.  
  213.   void resize (int n);
  214.   void resize (int n, const T& val);
  215.  
  216.   const T *data (void) const { return rep->data; }
  217.  
  218.   T *fortran_vec (void);
  219.  
  220.   Array<T>& qsort (int (*compare) (const void *, const void *))
  221.     {
  222.       make_unique ();
  223.  
  224.       rep->qsort (compare);
  225.  
  226.       return *this;
  227.     }
  228.  
  229.   T range_error (const char *fcn, int n) const;
  230.   T& range_error (const char *fcn, int n);
  231.  
  232. #ifdef HEAVYWEIGHT_INDEXING
  233.   void set_max_indices (int mi) { max_indices = mi; }
  234.  
  235.   void clear_index (void);
  236.  
  237.   void set_index (const idx_vector& i);
  238.  
  239.   int index_count (void) const { return idx_count; }
  240.  
  241.   idx_vector *get_idx (void) const { return idx; }
  242.  
  243.   void maybe_delete_elements (idx_vector& i);
  244.  
  245.   Array<T> value (void);
  246.  
  247.   Array<T> index (idx_vector& i) const;
  248. #endif
  249. };
  250.  
  251. template <class LT, class RT>
  252. int assign (Array<LT>& lhs, const Array<RT>& rhs);
  253.  
  254. #endif
  255.  
  256. /*
  257. ;;; Local Variables: ***
  258. ;;; mode: C++ ***
  259. ;;; End: ***
  260. */
  261.